package com.edu;

import interceptor.InterceptorChain;
import test.DefatultHandler;
import util.HandlerDefinitionParser;
import view.ContentViewResult;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

public class DispatcherServlet extends HttpServlet {

    private static final String METHOD = "handle";

    protected static final String DEFINITIONS = "DEFINITIONS";

    protected static final String INTERCEPTORS = "INTERCEPTORS";

    public static final String CLASSPATH = "CLASSPATH";

    private Map<String,HandlerDefinition> map = new HashMap<>();

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        initMethod(config);
        initInterceptor(config);
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        ActionContext actionContext = ActionContext.getContext();
        actionContext.setRequest(req);
        actionContext.setResponse(resp);

        InterceptorChain chain = new HandlerMapping().findHandler(req);
        HandlerDefinition definition = chain.getDefinition();
        if (definition==null){
            new DefatultHandler().handle(req,resp);
        }else{
            Object result = chain.handle();
            renderView(result);
        }
    }

    private void renderView(Object result){
        if (result==null) return;

        if (result instanceof ViewResult){
            ((ViewResult)result).execute();
        }else{
            ((ContentViewResult)result).execute();
        }
    }

    private void initMethod(ServletConfig config){

        List<HandlerDefinition> definitions = HandlerDefinitionParser.parseDifinition();
        for (HandlerDefinition definition:definitions){
            map.put(getMappingName(definition),definition);
        }
        config.getServletContext().setAttribute(DEFINITIONS,map);
    }

    private void initInterceptor(ServletConfig config){
        List<Class<?>> interceptorList =  HandlerDefinitionParser.parseInterceptor();
        config.getServletContext().setAttribute(INTERCEPTORS,interceptorList);
    }


    private String getMappingName(HandlerDefinition definition){
        return "/"+definition.getMethod().getName();
    }
}
